package com.livelab.java;

import com.livelab.model.AssignedExercise;
import com.livelab.util.MySQLDatabaseUtil;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Map;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;

/**
 * Backing bean supports "assignExercise.xhtml"
 * 
 * @author Dakota
 */
@ManagedBean
@RequestScoped
public class AssignBean {

    private static final String INSERT = "INSERT INTO exerciseassigned VALUES(?,?,?,?,?);";
    private static final String UPDATE = "UPDATE exerciseassigned SET dueDate = ?, score = ? WHERE exerciseName = ? AND username = ?;";
    
    /* GETTERS & SETTERS */
    private ArrayList<String> assignedItems;        //all assigned exercises
    private ArrayList<String> defaultExerciseItems; //all default exercise
    private ArrayList<String> customItems;          //all custom exercises(N/A)
    
    /* GETTERS ONLY */
    private TreeMap<String, String> assigned;               //selected assigned
    private TreeMap<String, String> defaultExercise;        //selected default
    private TreeMap<String, String> custom;                 //selected custom(N/A)
    
    private ArrayList<AssignedExercise> assignedTableList; //assigned exercise info
    private MySQLDatabaseUtil db;
    
    @ManagedProperty(value="#{instructorLoginBean}")
    private InstructorLoginBean loginBean;      //instructor login bean reference
    
    private String[] timezones;                 //all timezones
    private String selectedTimezone;            //selected timesone
   
    /**
     * Constructor
     */
    public AssignBean() {
        db = new MySQLDatabaseUtil("localhost/javalivelab9e", "agsuser", "agsuser");
                
        //loaded into SelectManyList in order
        assigned = new TreeMap<String, String>();
        defaultExercise = new TreeMap<String, String>();
        custom = new TreeMap<String, String>();

        //selected items from the SelectManyList
        assignedItems = new ArrayList<String>();
        defaultExerciseItems = new ArrayList<String>();
        customItems = new ArrayList<String>();

        assignedTableList = new ArrayList<AssignedExercise>();
        
        //populate timezones
        timezones = TimeZone.getAvailableIDs();
        Arrays.sort(timezones);
    }
    
    @PostConstruct
    public void init(){
        ResultSet rs;
        
        //populate the assigned exercise list from database.
        rs = db.executeQuery("SELECT * FROM exerciseassigned where username='" + loginBean.getUsername() + "';");
        try {
            while (rs.next()) {
                assigned.put(rs.getString("exerciseName"), rs.getString("exerciseName"));
                assignedTableList.add(new AssignedExercise(rs.getString(1), rs.getString(2), rs.getTimestamp(3), rs.getTimestamp(4), rs.getDouble(5)));
            }
        } catch (SQLException ex) {
            Logger.getLogger(AssignBean.class.getName()).log(Level.SEVERE, null, ex);
        }
            
        //populate the default exercise list from database
        rs = db.executeQuery("SELECT exercisename FROM defaultexercise");
        try {
            while (rs.next()) {
                if (!assigned.containsKey(rs.getString("exerciseName"))) {
                    defaultExercise.put(rs.getString("exerciseName"), rs.getString("exerciseName"));
                }
            }
        } catch (SQLException ex) {
            Logger.getLogger(AssignBean.class.getName()).log(Level.SEVERE, null, ex);
        }

        //populate the custom exercise list
        rs = db.executeQuery("SELECT exerciseName FROM customExercise");
        try {
            while (rs.next()) {
                custom.put(rs.getString("exerciseName"), rs.getString("exerciseName"));
            }
        } catch (SQLException ex) {
            Logger.getLogger(AssignBean.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
    
    /*
     * GETTERS
     */

    public ArrayList<AssignedExercise> getAssignedTableList() {
        return assignedTableList;
    }
    
    public Map<String, String> getAssignedValue() {
        return assigned;
    }

    public Map<String, String> getDefaultExerciseValue() {
        return defaultExercise;
    }

    public Map<String, String> getCustomValue() {
        return custom;
    }

    public ArrayList<String> getAssignedItems() {
        return assignedItems;
    }

    public ArrayList<String> getDefaultExerciseItems() {
        return defaultExerciseItems;
    }

    public ArrayList<String> getCustomItems() {
        return customItems;
    }
    
    public String getSelectedTimezone(){
        return selectedTimezone;
    }
    
    public String[] getTimezones(){
        return timezones;
    }
    
        
    public String getTimeZoneId(){
        ResultSet rs = db.executeQuery("SELECT timeZoneId from agsinstructor WHERE username = '" + loginBean.getUsername() + "';"); 
        try {
            if(rs.next())
                return rs.getString("timeZoneId");
            rs.close();
        } catch (SQLException ex) {
            
        }
        return "something";
    }
    
    /*
     * SETTERS
     */

    public void setAssignedItems(ArrayList<String> items) {
        this.assignedItems = new ArrayList(items);
    }

    public void setDefaultExerciseItems(ArrayList<String> items) {
        this.defaultExerciseItems = new ArrayList(items);
    }

    public void setCustomItems(ArrayList<String> items) {
        this.customItems = new ArrayList(items);
    }

    public void setSelectedTimezone(String selectedTimezone){
        this.selectedTimezone = selectedTimezone;
    }
    
    public void setAssignedTableList(ArrayList<AssignedExercise> assignedTableList) {
        this.assignedTableList = assignedTableList;
    }
    
    
    /*
     * ACTIONS
     */
    
    /**
     * Updates instructor time zone using the selected time zone
     */
    public void setTimezone(){
        FacesContext context = FacesContext.getCurrentInstance();
        db.executeStatement("UPDATE agsinstructor SET timeZoneId='" + selectedTimezone + "' WHERE username='" + loginBean.getUsername() + "';");
        context.addMessage(null, new FacesMessage("Time Zone", "Updated to " + selectedTimezone));
    }

    /**
     * Set default exercises selected as assigned exercises
     */
    public void assignDefaultExercises() {
        db.setPreparedStatement(INSERT);
        FacesContext context = FacesContext.getCurrentInstance();
        //for each selected default exercise
        for (String selectedItem : defaultExerciseItems) {
            //create an assigned exercise
            AssignedExercise temp = new AssignedExercise(loginBean.getUsername(), selectedItem);
            //insert into database
            db.executePreparedStatement(temp.toArray());
        }
        
        context.addMessage(null, new FacesMessage("Assign Exercises", "Success"));
    }

    /**
     * Remove assigned exercises selected from the database
     */
    public void removeAssigned() {
        FacesContext context = FacesContext.getCurrentInstance();
        //for each assigned exercise selected
        for (String selectedItem : assignedItems){
            db.executeStatement("DELETE FROM exerciseassigned WHERE username='" + loginBean.getUsername() + "' AND exerciseName='" + selectedItem + "';");
        }
            
        context.addMessage(null, new FacesMessage("Remove Exercises", "Success"));
    }
    
    /**
     * Update due date and max score for assigned exercises
     */
    public void updateAssigned() {
        PreparedStatement ps = db.getPreparedStatement(UPDATE);
        FacesContext context = FacesContext.getCurrentInstance();
        //for each assigned exercise in the table list
        for (AssignedExercise e : assignedTableList){
            try {
                ps.setTimestamp(1, e.getTimeStampDue());
                ps.setObject(2, e.getScore());
                ps.setString(3, e.getExerciseName());
                ps.setString(4, loginBean.getUsername());
                
                //update info in database
                ps.executeUpdate();
            } catch (SQLException ex) {
                context.addMessage(null, new FacesMessage("Update Table", "Failure"));
            }
        }
        
        context.addMessage(null, new FacesMessage("Update Table", "Success"));
    }
    
    /*
     * MANAGED PROPERTY SETTER
     */
    
    public void setLoginBean(InstructorLoginBean loginBean){
        this.loginBean = loginBean;
    }
}
